#include "StdAfx.h"
#include "sa_TwPick.h"


// define the keyboard macro
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)



sa_TwPick::sa_TwPick(void)
{
}

sa_TwPick::~sa_TwPick(void)
{
}
void sa_TwPick::InitGraphics()
{
	D3DXCreateTeapot(g_Render->GetDevice(), &meshTeapot, NULL);    // create the teapot
}

void sa_TwPick::InitRenderState()
{
	g_Render->GetDevice()->SetRenderState(D3DRS_ZENABLE, TRUE);
	g_Render->GetDevice()->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50));

	g_Render->GetDevice()->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, 8);    // anisotropic level
	g_Render->GetDevice()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);    // minification
	g_Render->GetDevice()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);    // magnification
	g_Render->GetDevice()->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);    // mipmap

}

void sa_TwPick::InitLight()
{
	D3DLIGHT9 light;    // create the light struct
	D3DMATERIAL9 material;    // create the material struct

	ZeroMemory(&light, sizeof(light));    // clear out the light struct for use
	light.Type = D3DLIGHT_DIRECTIONAL;    // make the light type 'directional light'
	light.Diffuse = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f);    // set the light's color
	light.Direction = D3DXVECTOR3(-1.0f, -0.3f, -1.0f);

	g_Render->GetDevice()->SetLight(0, &light);    // send the light struct properties to light #0
	g_Render->GetDevice()->LightEnable(0, TRUE);    // turn on light #0

	ZeroMemory(&material, sizeof(D3DMATERIAL9));    // clear out the struct for use
	material.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);    // set diffuse color to white
	material.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);    // set ambient color to white

	g_Render->GetDevice()->SetMaterial(&material);    // set the globably-used material to &material

}

void sa_TwPick::Update()
{

}

void sa_TwPick::Render()
{
	DetectPick();
	g_Render->GetDevice()->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
	g_Render->GetDevice()->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

	g_Render->GetDevice()->BeginScene();

	// set the view transform
	D3DXMATRIX matView;
	D3DXMatrixLookAtLH(&matView,
		&D3DXVECTOR3 (0.0f, 2.0f, 6.0f),    // the camera position
		&D3DXVECTOR3 (0.0f, 0.0f, 0.0f),      // the look-at position
		&D3DXVECTOR3 (0.0f, 1.0f, 0.0f));    // the up direction
	g_Render->GetDevice()->SetTransform(D3DTS_VIEW, &matView);

	// set the projection transform
	D3DXMATRIX matProjection;
	D3DXMatrixPerspectiveFovLH(&matProjection,
		D3DXToRadian(45),
		(FLOAT)800 / (FLOAT)600,
		1.0f,    // the near view-plane
		100.0f);    // the far view-plane
	g_Render->GetDevice()->SetTransform(D3DTS_PROJECTION, &matProjection);

	static float index = 0.0f; // index+=0.03f;

	// collect keyboard data
	if(KEY_DOWN(VK_LEFT)) index += 0.03f;
	if(KEY_DOWN(VK_RIGHT)) index -= 0.03f;

	// set the world transform
	D3DXMATRIX matRotateY;
	D3DXMatrixRotationY(&matRotateY, index);
	g_Render->GetDevice()->SetTransform(D3DTS_WORLD, &(matRotateY));

	// draw the teapot
	meshTeapot->DrawSubset(0);    

	g_Render->GetDevice()->EndScene(); 

	g_Render->GetDevice()->Present(NULL, NULL, NULL, NULL);

}

void sa_TwPick::Clear()
{
	meshTeapot->Release();
}
void sa_TwPick::DetectPick()
{
	// get the current transform matrices
	D3DXMATRIX matProjection, matView, matWorld, matInverse;
	g_Render->GetDevice()->GetTransform(D3DTS_PROJECTION, &matProjection);
	g_Render->GetDevice()->GetTransform(D3DTS_VIEW, &matView);
	g_Render->GetDevice()->GetTransform(D3DTS_WORLD, &matWorld);

	// use the mouse coordinates to get the mouse angle
	GetCursorPos(&MousePos);
	float xAngle = (((2.0f * MousePos.x) / SCREEN_WIDTH) - 1.0f) / matProjection(0, 0);
	float yAngle = (((-2.0f * MousePos.y) / SCREEN_HEIGHT) + 1.0f) / matProjection(1, 1);

	D3DXVECTOR3 origin, direction;
	origin = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
	direction = D3DXVECTOR3(xAngle, yAngle, 1.0f);

	// find the inverse matrix
	D3DXMatrixInverse(&matInverse, NULL, &(matWorld * matView));

	// convert origin and direction into model space
	D3DXVec3TransformCoord(&origin, &origin, &matInverse);
	D3DXVec3TransformNormal(&direction, &direction, &matInverse);
	D3DXVec3Normalize(&direction, &direction);

	// detect picking
	BOOL hit;
	D3DXIntersect(meshTeapot, &origin, &direction, &hit, NULL, NULL, NULL, NULL, NULL, NULL);
	if(hit)
		g_Render->GetDevice()->SetRenderState(D3DRS_LIGHTING, FALSE);
	else
		g_Render->GetDevice()->SetRenderState(D3DRS_LIGHTING, TRUE);

}